<template>
  <div
    :id="options.instanceCode"
    :style="styleCss"
    :class="styleClassList"
    @click="onClick"
    @dblclick="onDoubleClick"
    @mouseover="onMouseOver"
    del-mousemove="onMouseMove"
    @mouseout="onMouseOut"
    @touchstart="onTouchStart"
    @touchmove="onTouchMove"
    @touchend="onTouchEnd"
    @focus="onFocus"
    @blur="onBlur"
    @keydown="onKeyDown"
    @keyup="onKeyUp"
  >
    <ColConfWarp
      ref="ColConfWarp"
      @submit="columnConfigSubmit"
      :visible.sync="showColConf"
      v-if="!isDevEnv"
      :columns="options.columns"
      :dataGrid="widgetInstance"
      :gSortColumns="sortColumns"
      :hideSortConf="true"
    ></ColConfWarp>
    <DxTreeList
    :expanded-row-keys.sync="expandedRowKeys"
    :selected-row-keys="selectedRowKeys"
      :height="computedHeight"
      @initialized="onInitialized"
      :column-hiding-enabled="propColumnHidingEnabled"
      :remote-operations="computedOpts.lazyItems"
      :data-source="dataSource"
      :show-borders="true"
      :hover-state-enabled="true"
      :itemsExpr="computedOpts.itemsExpr"
      hasItemsExpr="_hasChildCode_"
      :keyExpr="computedDataStructure.keyExpr"
      :dataStructure="computedDataStructure.dataStructure"
      :parentIdExpr="computedDataStructure.parentIdExpr"
      :noDataText="computedOpts.noDataText"
      :autoExpandAll="computedOpts.autoExpandAll"
      :rowAlternationEnabled="true"
      :columnAutoWidth="computedOpts.columnAutoWidth"
      :filterMode="computedOpts.filterMode"
      @selection-changed="onSelectionChanged"
      @cellClick="onCellClick"
      @cellPrepared="onCellPrepared"
      @rowExpanded="onRowExpanded"
      @optionChanged="onOptionChanged"
      :rootValue="computedDataStructure.rootValue"
      :allowColumnResizing="
        computedOpts.allowColumnResizing === false ||
        computedOpts.allowColumnResizing === true
          ? computedOpts.allowColumnResizing
          : true
      "
      :columnResizingMode="computedOpts.columnResizingMode || 'widget'"
      @context-menu-preparing="onContextMenuPreparing"
    >
      <DxColumn
        :fixed="true"
        fixedPosition="left"
        :allowReordering="false"
        :caption="Term.dataGrid.sequenceNumber"
        width="80"
        v-if="computedOpts.showRowNumber"
        cell-template="rowNumber-cell-template"
      >
      </DxColumn>
      <template #rowNumber-cell-template="{ data }">
        <div> {{ data.rowIndex + 1 }}</div>
      </template>
      <!-- <DxFilterRow :visible="computedOpts.uiFilterMode == 'FilterRow'" /> -->
      <DxFilterRow :visible="computedOpts.showAutoFilterRow" />
      <DxSorting mode="none" />
      <DxSearchPanel :visible="computedOpts.uiFilterMode == 'SearchPanel'" />
      <DxHeaderFilter :visible="computedOpts.uiFilterMode == 'HeaderFilter'" />
      <DxFilterPanel :visible="computedOpts.uiFilterMode == 'FilterPanel'" />
      <DxSelection
        v-if="computedOpts.selectMode != 'none'"
        :recursive="computedOpts.recursiveSelection"
        :mode="computedOpts.selectMode"
      />
      <DxColumn
        :minWidth="computedColumnMinWidth"
        v-for="(col, i) in computedColumns"
        :key="i"
        v-bind="col"        
        :cell-template="dynamicCellTemplate(col, i)"
        :edit-cell-template="dynamicEditCellTemplate(col, i)"
        :calculate-group-value="col.dataField"
      />
      <DxColumn
        v-if="optsCmdColConf.columnConf"
        type="buttons"
        css-class="colCmd"
        -width="auto"
        :visible="options.enableCmdCol == true"
        :width="optsCmdColConf.columnConf.width"
        :caption="optsCmdColConf.columnConf.caption"
        :fixed="optsCmdColConf.columnConf.fixed"
        :fixedPosition="optsCmdColConf.columnConf.fixedPosition"
      >
        <DxButton
          v-for="(cmd, i) in computedColCmdsWithAlwaysShow"
          :key="i"
          :text="cmd.text"
          :icon="cmd.icon"
          :hint="cmd.text"
          :visible="
            (e) => {
              return colCommandVisible(cmd, e);
            }
          "
          :on-click="
            (e) => {
              colCommandHandler(cmd, e);
            }
          "
        />
        <DxButton
          icon="more"
          :visible="hasMoreCmd"
          :on-click="colMoreCommand"
        />
      </DxColumn>

      <DxColumn width="0" v-if="false"></DxColumn>
      
      <template #link-cell-template="{ data }">
        <div style="">
          <span
            class="cellLinkHref"
            @click="cellLinkHref(data)"
            :title="data.value"
            >{{ data.value }}
          </span>
        </div>
      </template>

      <template #enum-cell-template="{ data: cellInfo }">
        <div style="text-align: center">
          <EnumCol :cellInfo="cellInfo" :isDevEnv="isDevEnv" :columns="options.columns"></EnumCol>
        </div>
      </template>

      <template #link-enum-cell-template="{ data }">
        <div style="text-align: center; cursor: pointer;" @click="cellLinkHref(data)">
          <EnumCol :cellInfo="data" :isDevEnv="isDevEnv" :columns="options.columns"></EnumCol>
        </div>
      </template>
      <template #link-format-cell-template="{ data }">
        <div style="">
          <span class="cellLinkHref" @click="cellLinkHref(data)" :title="calculateDisplayValueWithLinkFormat(data)">{{calculateDisplayValueWithLinkFormat(data) }}</span>
        </div>
      </template>

    </DxTreeList>
  </div>
</template>
<style src="./style/index.css"></style>
<script>
import _ from "lodash";
import BaseFasComponent, {
  MakePublicProp,
  MakePublicMethod,
} from "../BaseDevExtreme";
// import * as devextreme from "devextreme-vue/tree-list";
import { MixinsFill } from "../../mixins/mixinsFill";
import { MixinsLZString } from "../../mixins/mixinsLZString";
import EnumCol from "../dxDataGrid/enumCol.vue";
import ColConfWarp from "../dxDataGrid/colConfWarp.vue";
import { ColumnConfig } from "../../widget/MixedView/ColumnConfig";
import FormatFunctions from "../../../util/FormatFunctions";
import treeConvert from "../../../util/tree-convert";
import TermsTreeList from "./TermsTreeList";
import { formatDate } from "devextreme/localization";

let merge = {
  CompID: "dxTreeList_v2",
  CompName: "FAS-DX-TreeList-v2",
  Tag: "fas-dx-treelist-v2",
  DeviceType: ["pc", "pad", "mobile"],
};
let compMeta = { ...merge };

let DebounceFuncs = {
  refreshColumnsAndSubmitDebounce: _.debounce(function (that) {
    that.$refs.ColConfWarp.RefreshColumnsAndSubmit();
  }, 1000),
  emitTreeGridChangedDebounce: _.debounce(function (that) {
    that.emitTreeGridChanged();
  }, 1000),
  emitTreeGridOptionChangedEventDebounce: _.debounce(function (that) {
    that.emitTreeGridChanged(true);
  }, 1000),
  Exec(func, that) {
    func.cancel();
    func(that);
  },
};

export default {
  name: compMeta.Tag,
  // fasConf: compMeta,
  mixins: [MixinsFill, MixinsLZString],
  extends: BaseFasComponent,
  components: {
    ColConfWarp,
    EnumCol,
    // ...devextreme,
    DxTreeList: function (resolve) {
      resolve(require("devextreme-vue/tree-list").DxTreeList);
    },
    DxFilterRow: function (resolve) {
      resolve(require("devextreme-vue/tree-list").DxFilterRow);
    },
    DxSorting: function (resolve) {
      resolve(require("devextreme-vue/tree-list").DxSorting);
    },
    DxSearchPanel: function (resolve) {
      resolve(require("devextreme-vue/tree-list").DxSearchPanel);
    },
    DxHeaderFilter: function (resolve) {
      resolve(require("devextreme-vue/tree-list").DxHeaderFilter);
    },
    DxFilterPanel: function (resolve) {
      resolve(require("devextreme-vue/tree-list").DxFilterPanel);
    },
    DxSelection: function (resolve) {
      resolve(require("devextreme-vue/tree-list").DxSelection);
    },
    DxColumn: function (resolve) {
      resolve(require("devextreme-vue/tree-list").DxColumn);
    },
    DxRemoteOperations: function (resolve) {
      resolve(require("devextreme-vue/tree-list").DxRemoteOperations);
    },
  },
  created() {
    if (!this.isDevEnv) {
      if (window.FASEnvironment)
        this.localStorageKey = `P:${
          FASEnvironment.getCurrentInstance().pageMetaData.ID
        }|W:${this.InstanceCode}`;
      else
        this.localStorageKey = `P:${window.pageMetaData.ID}|W:${this.InstanceCode}`;
      this.localStorageKey_columnsWidth = `${this.localStorageKey}.columnsWidth`;
    }
  },
  mounted(){
    if (this.options.lazyItems && !this.options.dataSource.LoadDataTime && true !== this.isDevEnv && !this.options.MixedViewIC) {
      this.loadByLazyCode(this.IsLevelStructure ? "" : this.options.rootValue);
    } else {
      if (true !== this.options.lazyItems) {
        if (!this.options.MixedViewIC) {
          this.initDataSource();
        } else if (Widget[this.options.MixedViewIC] && !Widget[this.options.MixedViewIC].advQueryWidget) {
          this.initDataSource();
        }
      }
    }
  },
  methods: {
    convertLevel2ParentId: treeConvert.convertLevel2ParentId,
    ClearSelection() {
      this.widgetInstance.clearSelection();
    },
    loadData(reload) {
      this.widgetInstance.clearSelection();
      this.selectedRows = [];
      this.reloadDataSource(reload);
    },
    Refresh() {
      if(this.options.lazyItems){
        if(this)
        this.dataSource = [];
        this.$nextTick(()=>{
          this.CollapsAll();
          this.loadByLazyCode(this.IsLevelStructure ?  "" : this.options.rootValue);
        });
        
        return;
      }
      this.loadData(true);
    },
    onSelectionChanged({ selectedRowsData }) {
      if(this.ReadOnly){
        return
      }
      this.selectedRows = selectedRowsData;
      this.triggerEventHandler("OnSelectionChanged", arguments);
    },
    onCellClick({ row, rowType }) {
      if (
        rowType == "data" &&
        row &&
        row.isSelected &&
        this.options.selectMode == "single" &&
        this.options.enableUnSelect
      ) {
        setTimeout(() => {
          this.ClearSelection();
        });
      }
    },

    loadByLazyCode(lazyCode) {
      let node = this.widgetInstance.getNodeByKey(lazyCode);
      if(node && _.size(node.children)>0){
        return;
      }
      this.LazyCode = lazyCode;
      this.SetLoadState(true);
      this.loadDataFormActionListCallback((data) => {
        let actionBindPath = this.getActionDataBind();
        if (_.has(data, actionBindPath)) {
          let nodes = _.get(data, actionBindPath);
          nodes = _.each(nodes, (node) => {
            if (this.IsLevelStructure) { node[this.computedLevelParentIdExpr] = this.LazyCode; }
            node._hasChildCode_ = !(
              `${node[this.options.hasItemsExpr]}` ==
              `${this.options.leafValue == "custom" ? this.options.hasItemsExprValue : this.options.leafValue}`
            );
          });
          // resolve(nodes);
          this.dataSource = [...this.dataSource, ...nodes]
        } else {
          this.$message({
            message: `Action 返回类型不符合预期,期望List (检查组件ID:${this.InstanceCode}数据源设置)`,
            type: "warning",
          });
          resolve([]);
        }
        this.SetLoadState(false);
      },
        (dsParameters) => {
          let dsParams = _.cloneDeep(dsParameters);
          let widgetInstanceCode = this.options.instanceCode;
          if (this.options.MixedViewIC) {
            widgetInstanceCode = `${this.options.MixedViewIC}.TreeGridInstance`;
          }

          let advancedFilter = _.find(dsParams, { Code: "AdvancedFilter" });
          if (advancedFilter) {

            if (_.isEmpty(advancedFilter.Value)) {
              advancedFilter.Value = `Widget.${widgetInstanceCode}.appendLazyFilter()`;
            } else {
              advancedFilter.Value = `Widget.${widgetInstanceCode}.appendLazyFilter(${advancedFilter.Value})`;
            }
          }

          let fasDynamicFilter = _.find(dsParams, { Code: "FasDynamicFilter" });
          if (fasDynamicFilter) {
            if (_.isEmpty(fasDynamicFilter.Value)) {
              fasDynamicFilter.Value = `Widget.${widgetInstanceCode}.GetFasLazyCode()`;
            } else {
              /*
              // 有条件不需要处理
              fasDynamicFilter.Value = `({...${fasDynamicFilter.Value}, ...Widget.${widgetInstanceCode}.GetFasLazyCode()})`;
              */
            }
          }

          return dsParams;
        }
      );
    },
    onCellPrepared(e) {
      this.CellPreparedInfo = e;
      this.triggerEventHandler("OnCellPrepared", arguments, true);
    },
    onRowExpanded({component,element,key}){
      if(this.options.lazyItems){
        this.isRowExpanded = true;
        this.loadByLazyCode(key);
      }
    },
    ExpandAll(){
      this.expandedRowKeys = _.map(this.dataSource,this.computedDataStructure.keyExpr);
    },
    CollapsAll(){
      this.expandedRowKeys = [];
    },
    RefreshByData(data, mapFun) {
      var ds = _.defaults(data, { List: [], Count: 0 });
      if (mapFun) {
        ds.List = _.map(ds.List, mapFun);
      }
      this.dataSource = ds.List;
      this.totalCount = ds.Count;
      setTimeout(() => {
        //处理控件通过页导航时第二页页面不对
        this.totalCount = ds.Count;
      }, 1);
      return ds;
    },
    onContextMenuPreparing: function (e) {
      if (e.target === "header") {
        ColumnConfig.HeaderColumnConfig.bind(this)(e);
        
        if (e.columnIndex == 0) {
          e.items.push({
            icon: this.IsExpandAll ? "inactivefolder" : 'folder',
            text: this.IsExpandAll ? TermsTreeList.title.collapsAll : TermsTreeList.title.expandAll,
            onItemClick: () => {
              this.IsExpandAll ? this.CollapsAll() : this.ExpandAll()              
            },
          });
        }
      }
    },
    columnConfigSubmit(playload) {
      debugger;
      let colSortQuery = _.get(this, "options.colSortQuery", true);
      if (colSortQuery) {
        this.updateAdvQueryFlagExecQuery = true;
      }
      this.ColumnConfigSubmitCB(playload);
      // if(this.scheme){
      //   this.scheme.sortColumns = this.sortColumns;
      // }
      this.emitTreeGridChanged();
    },
    ColumnConfigSubmitCB: ColumnConfig.ColumnConfigSubmitCB,
    ShowColumnConf() {
      this.showColConf = true;
    },
    _rebindcomputedColumns(columns) {
      setTimeout(() => {
        let offset = this.options.showRowNumber ? 1 : 0;
        _.each(columns, (col, i) => {
          let colSort = { sortIndex: "", sortOrder: "" };
          if (this.sortColumns) {
            let findSortCol = _.find(this.sortColumns, {
              value: col.dataField,
            });
            if (findSortCol) {
              colSort = {
                sortIndex: findSortCol.sortIndex,
                sortOrder: findSortCol.sortOrder,
              };
            }
          }
          let colOpt = {
            visibleIndex: i + offset,
            sortIndex: colSort.sortIndex,
            sortOrder: colSort.sortOrder,
          };
          this.widgetInstance.columnOption(col.name, colOpt);
        });
      });
    },
    syncColConfWarpColumns() {
      if (this.$refs.ColConfWarp) {
        let currentColumns = this.$refs.ColConfWarp.getCurrentColumns();

        let mergeSortColumns = this.$refs.ColConfWarp.mergeSortColumns(
          _.cloneDeep(this.sortColumns),
          currentColumns
        );
        currentColumns.sortColumns = mergeSortColumns;

        let { displayColumns, sortColumns } = currentColumns;

        this.displayColumnsSync = displayColumns;
        this.sortColumns = this.sortColumnsSync = sortColumns;
      }
    },
    getColumnsWidthFromStorage() {
      let returnValue = [];
      if (false === this.options.saveColumnWidth) {
        return returnValue;
      }
      let val = this.LZStringGetStorage(
        localStorage,
        this.localStorageKey_columnsWidth
      );

      if (val) {
        returnValue = JSON.parse(val);
        _.remove(returnValue, function (n) {
          return 0 == n.vw || ("buttons" == n.type && "colCmd" == n.cssClass);
        });
      }
      return returnValue;
    },
    debounceColumnsWidth: _.debounce(function (e) {
      if (false === this.options.saveColumnWidth) {
        return;
      }
      let visibleWidths = _.map(e.component.getVisibleColumns(), (item) => {
        return { df: item.dataField, vw: item.visibleWidth };
      });
      _.remove(visibleWidths, function (n) {
        return (
          false === _.isNumber(n.vw) ||
          0 == n.vw ||
          ("buttons" == n.type && "colCmd" == n.cssClass)
        );
      });
      this.LZStringSetStorage(
        localStorage,
        this.localStorageKey_columnsWidth,
        JSON.stringify(visibleWidths)
      );
    }, 1000),

    onOptionChanged(e) {
      if (e.name === "columns") {
        if (e.fullName.endsWith(".width")) {
          this.debounceColumnsWidth(e);
          this.OnTreeGridChangedSyncArgs = { isForce: true };
          DebounceFuncs.Exec(
            DebounceFuncs.emitTreeGridOptionChangedEventDebounce,
            this
          );
        } else if (e.fullName.endsWith(".visibleIndex")) {
          this.OnTreeGridChangedSyncArgs = { isForce: true };
          DebounceFuncs.Exec(
            DebounceFuncs.emitTreeGridOptionChangedEventDebounce,
            this
          );
        } else if (e.fullName.endsWith(".sortOrder")) {
          let colSortQuery = _.get(this, "options.colSortQuery", true);
          if (colSortQuery == false) {
            this.OnTreeGridChangedSyncArgs = { isForce: true };
            DebounceFuncs.Exec(
              DebounceFuncs.emitTreeGridOptionChangedEventDebounce,
              this
            );
          }
        } else if(e.fullName.endsWith(".selectedFilterOperation") || e.fullName.endsWith(".filterValue")){
          if(e.value == null){
            let expRowKeys = [...this.expandedRowKeys]
            setTimeout(() => {
              this.expandedRowKeys =  expRowKeys;
            },10);
          }
        }
      }
    },
    emitTreeGridChanged(isCallSyncColConfWarpColumns) {
      if (isCallSyncColConfWarpColumns) {
        this.syncColConfWarpColumns();
      }
      this.triggerEventHandler("OnTreeGridChangedSync");
    },
    SetSchemeBase(scheme) {
      this.CollapsAll();
      let displayColumns = scheme.displayColumns;
      if (!displayColumns || displayColumns.length == 0) {
        displayColumns = _.filter(this.options.columns, { isShow: true });
        displayColumns = _.map(displayColumns, (col) => {
          let newCol = {
            label: col.caption,
            value: col.dataField,
            width: col.width,
          };
          // if (col.width) {
          //   newCol.width = col.width;
          // }
          return newCol;
        });
        scheme.displayColumns = _.cloneDeep(displayColumns);
        scheme.sortColumns = [];
      }

      let playload = {
        sortColumns: scheme.sortColumns,
        displayColumns: displayColumns,
      };
      if (scheme.pageSize) {
        this.PageSize = scheme.pageSize;
      }
      if (_.has(scheme, "showAutoFilterRow")) {
        this.ShowAutoFilterRow = scheme.showAutoFilterRow;
      }
      this.widgetInstance.clearFilter();
      if (this.skipWithRTFlag === true) {
        /** 手动调试开关 */
        return;
      }
      this.ColumnConfigSubmitCB(playload);
    },
    SetScheme(scheme) {
      this.scheme = _.cloneDeep(scheme);
      this.SetSchemeBase(scheme);
    },
    GetScheme() {
      let valueValue = {
        pageSize: this.PageSize,
        showAutoFilterRow: this.ShowAutoFilterRow,
        // displayColumns: this.displayColumns,
        // sortColumns: this.sortColumns,
        displayColumns: this.displayColumnsSync,
        sortColumns: this.sortColumnsSync,
      };
      return valueValue;
    },

    dynamicEditCellTemplate() {
      return "";
    },
    cellLinkHref(data) {
      debugger;
      // let linkFormat = this.options.columns[data.column.index].linkFormat;
      let linkFormat = _.find(this.options.columns, {
        dataField: data.column.dataField,
      }).linkFormat;
      if (linkFormat) {
        this.CellClickInfo = data.data;
        this.execClientScript(linkFormat);
      }
    },
    dynamicCellTemplate(col, i) {
      let returnValue = "";
      let hasLinkFormat = false == _.isEmpty(col.linkFormat);
      let hasEnumDisp = col.enumDisp && col.enumDisp.enumRanges && col.enumDisp.enumRanges.length > 0

      if(hasLinkFormat && hasEnumDisp){
        returnValue = "link-enum-cell-template";
      } else if (hasLinkFormat) {
        returnValue = "link-cell-template";
      } else if (hasEnumDisp) {
        returnValue = "enum-cell-template";
      }
      return returnValue;
    },
    dynamicCellTemplate(col, i) {      
      let returnValue = "";
      let hasLinkFormat = false == _.isEmpty(col.linkFormat);
      let hasEnumDisp = col.enumDisp && col.enumDisp.enumRanges && col.enumDisp.enumRanges.length > 0
      let hasFormat = col.dataFormat && col.dataFormat.FormatType
      let isDateCol = col && (col.dataType == "date" || col.dataType == "datetime") && col.format
      if (hasLinkFormat && hasEnumDisp) {
        returnValue = "link-enum-cell-template";
      } else if (hasLinkFormat && (hasFormat || isDateCol)) {
        returnValue = "link-format-cell-template";
      } else if (hasLinkFormat) {
        returnValue = "link-cell-template";
      } else if (hasEnumDisp) {
        returnValue = "enum-cell-template";
      }
      return returnValue;
    },
    calculateDisplayValueWithLinkFormat(cellTempData) {
      let { value, column } = cellTempData
      let col = _.find(this.computedColumns, { dataField: column.dataField });
      if (col && col.dataFormat && col.dataFormat.FormatType) {
        let cellInfo = {
          value: value,
          valueText: value
        }
        return this.customizeText(cellInfo, col)
      } else if (col && (col.dataType == "date" || col.dataType == "datetime") && col.format) {
        const dateString = formatDate(value, col.format);
        return dateString
      }
      else {
        return value
      }
    },
    calculateDisplayValue(rowData, col) {
      let cellInfo = {
        value: rowData[col.dataField],
        valueText: rowData[col.dataField],
      };

      return this.customizeText(cellInfo, col);
    },
    customizeText(cellInfo, col) {
      if (col.dataFormat && col.dataFormat.FormatType) {
        let formated = this.colFormat(cellInfo, col);
        return formated;
      }
      return cellInfo.valueText;
    },
    calculateFilterExpressionCol(value, selectedFilterOperations, target, col) {
      const column = this.widgetInstance.columnOption(col.dataField);
      if (target === "filterRow") {
        if (col && col.enumDisp && col.enumDisp.enumRanges) {
          return [`${col.dataField}_$mapping`, selectedFilterOperations, value];
        }
      }
      return column.defaultCalculateFilterExpression(
        value,
        selectedFilterOperations,
        target
      );
    },
    calculateFilterExpressionDiscount(value, selectedFilterOperations, target, col) {
      debugger;
      const column = this.widgetInstance.columnOption(col.dataField);
      if (Funcs.extractDiscount) {
        if (_.isArray(value)) {
          value = _.map(value, v => v == null ? v : Funcs.extractDiscount(`${v}`));
          value = value.reverse();
        } else {
          value = Funcs.extractDiscount(`${value}`)
        }
      }
      switch (selectedFilterOperations) {
        case "<":
          selectedFilterOperations = ">"
          break;
        case "<=":
          selectedFilterOperations = ">="
          break;
        case ">":
          selectedFilterOperations = "<"
          break;
        case ">=":
          selectedFilterOperations = "<="
          break;
      }
      return column.defaultCalculateFilterExpression(value, selectedFilterOperations, target);
    },
    calculateFilterExpressionPercent(value, selectedFilterOperations, target, col) {
      const column = this.widgetInstance.columnOption(col.dataField);
      if (_.isArray(value)) {
        value = _.map(value, v => v / 100);
      } else {
        value = value / 100
      }
      return column.defaultCalculateFilterExpression(value, selectedFilterOperations, target);
    },
    colFormat(cellInfo, col) {
      let formatFunc =
        FormatFunctions[col.dataFormat.FormatType] ||
        ((cellInfo) => cellInfo.valueText);
      return formatFunc(cellInfo, col);
    },
    dynamicEditCellTemplate() {
      return "";
    },
    SetIgnoreParams(ignoreParams){
      this.ignoreParams = ignoreParams;
    },
    getHasFilter(isCheckAdvancedFilter){
      this.hasFilter = false;
      let skipArray = ['PageIndex', 'PageSize', 'AdvancedSort', "-FasDynamicFilter", "FasDynamicSort", ...this.ignoreParams]
      if (true !== isCheckAdvancedFilter) {
        skipArray.push('AdvancedFilter');
      }
      _.each(this.options.dataSource.Parameters, param=>{
        if(false == skipArray.includes(param.Code)){

          if (param.Code == 'FasDynamicFilter') {
            // 检查调用Action时动态参数是不是有条件
            if (param.Value && param.Value.includes('.GetFasDynamicFilter()')) {
              let vmIn = Widget[this.options.MixedViewIC];
              if (vmIn && vmIn.QueryFilterIsEmpty && false == vmIn.QueryFilterIsEmpty()) {
                this.hasFilter = true;
                return false;
              }
              return;
            }
          }

          let paramVal = this.execExpression(param.Value);

          if (param.Code == 'AdvancedFilter') {
            if (paramVal) {
              paramVal = JSON.parse(paramVal);
              if (paramVal.Filters && _.size(paramVal.Filters) > 0) {
                this.hasFilter = true;
                return false;
              }
            }
          } else {
            if (false == _.isNil(paramVal) && `${paramVal}`) {
              this.hasFilter = true;
              return false;
            }
          }
        }
      });
      return this.hasFilter;
    },
    appendLazyFilter(filter){
      debugger;
      this.getHasFilter();

      if(this.hasFilter){
        return filter;
      }

      if(this.IsLevelStructure){
        return this.appendLevelFilter(filter);
      }else{
        return this.appendParentFilter(filter);
      }
    },
    GetFasLazyCode() {
      this.getHasFilter(true);
      if (false == this.hasFilter && this.options.lazyItems) {
        let returnValue = {};
        returnValue[this.computedDataStructure.keyExpr] = this.GetLazyCode();
        return returnValue
      } else {
        return {};
      }
    },
    GetLazyCode() {
      if (this.IsLevelStructure) {
        return this.calcLazyLevelCode();
      } else {
        return this.LazyCode;
      }
    },
    calcLazyLevelCode(){
      let nextLevel = this.LazyCode;
      let {
        isClassiFicationSteps = false,
        classiFicationStep = 3,
        classiFicationStepRule = "2-3"
      } = this.options;

      let levelLen = 0;
      if (isClassiFicationSteps) {
        levelLen = +classiFicationStep
      } else {
        let step = 0;
        let stepRuleArray = `0-${classiFicationStepRule}`.split("-");
        let stepMapping = _.transform(stepRuleArray, (result, value, index) => {
          result[step += (+value)] = +stepRuleArray[index == stepRuleArray.length - 1 ? index : index + 1]
        }, {});

        levelLen = stepMapping[nextLevel.length] || stepMapping[_.max(_.keys(stepMapping))]
      }
      return `${nextLevel}${_.repeat("_", levelLen)}`;
    },
    appendLevelFilter(filterStr) {
      let filter = filterStr || {}
      if(_.isString(filter)){
        filter = JSON.parse(filter)
      }

      if(this.hasFilter){
        return filterStr;
      }

      if (_.size(filter.Filters) != 0 && this.LazyCode=="") {
        this.hasFilter = true;
        return filterStr;
      }

      this.isRowExpanded = false;

      let nextLevelVal = this.calcLazyLevelCode();

      let levelColumn = _.find(this.options.columns,{dataField:this.options.levelKeyExpr});

      if(!levelColumn){
        return filter;
      }
      let { originalName: realField, tableAlias } = levelColumn;

      let returnValue = {
        ElementType: "Group",
        Filters: [
          {
            ElementType: "Filter",
            Code: `${tableAlias}.${realField}`,
            Condition: "fixedlengthcontains",
            Value: nextLevelVal
          },
        ],
      };

      if(filter && _.size(filter.Filters)>0){
        returnValue.Filters.push(
          {
            ElementType: "Relation",
            Relation: "and",
          },
          {...filter}
        )
      }
      return JSON.stringify(returnValue);
    },
    appendParentFilter(filterStr) {
      debugger;
      let filter = filterStr || {}
      if(_.isString(filter)){
        filter = JSON.parse(filter)
      }

      if(this.hasFilter){
        return filterStr;
      }

      if (_.size(filter.Filters) != 0) {
        this.hasFilter = true;
        return filterStr;
      }

      let {
        parentIdExpr
      } = this.options;

      let parentIdColumn = _.find(this.options.columns,{dataField:parentIdExpr});

      if(!parentIdColumn){
        return filter;
      }
      let { originalName: realField, tableAlias } = parentIdColumn;

      let returnValue = {
        ElementType: "Group",
        Filters: [
          {
            ElementType: "Filter",
            Code: `${tableAlias}.${realField}`,
            Condition: "fixedlengthcontains",
            Value: `${this.LazyCode}` 
          },
        ],
      };

      if(filter && _.size(filter.Filters)>0){
        returnValue.Filters.push(
          {
            ElementType: "Relation",
            Relation: "and",
          },
          {...filter}
        )
      }
      
      return JSON.stringify(returnValue);
    },
    onInitialized(e){
      this.saveWidgetInstance(e);

      setTimeout(() => {
        this.initObserverScrollableScrollStyle(e.element);
      },1000);      
    },
    initObserverScrollableScrollStyle(element){
      if (this.isDevEnv) {
        return;
      }
      var target = element.querySelector('.dx-scrollable-scroll');
      if (target) {
        this.observerScrollableScrollStyle.observe(target, { attributes: true, attributeFilter: ['style'] });
      }
    },
    cbScrollableScrollStyleMutationObserver(mutations) {
      mutations.forEach((mutationRecord) => {
        this.widgetInstance.element().querySelector(".dx-treelist-columns-separator").style.left = '-5px';
      });
    },
  },
  computed: {
    computedColumnMinWidth(){
      let cssClass = this.CSSClass() ||[];
      let hasHideHeader = cssClass.includes('hideHeader'); /** 看板无表头兼容处理 */
      return _.size(this.dataSource) == 0 && _.size(this.computedColumns) > 0 && false == hasHideHeader ? 150 : undefined;
    },
    ...MakePublicProp([
      "Visible",
      "ShowAutoFilterRow",
      ["SelectedRows"], //二层字符串固定从this中取
    ]),
    IsExpandAll(){
      return _.size(this.expandedRowKeys) == _.size(this.dataSource);
    },
    bak_computedColumns() {
      let columns = this.options.columns;
      if (this.ColumnsInfo && this.ColumnsInfo.UseColumnContent) {
        columns = this.ColumnsInfo.columnsInfo.map((m) => {
          return {
            ...this.options.columns.find((f) => f.ID == m.ID),
            ...m,
          };
        });
      }
      columns = _.filter(columns, { isShow: true });
      columns = _.map(columns, (col) => {
        if (col.dataType == "Date" || col.dataType == "date") {
          let dataCol = { ...col };
          dataCol.dataType = "date";
          dataCol.format = "yyyy-MM-dd";
          return dataCol;
        } else {
          return _.omit(col, ["dataType"]);
        }
      });
      return columns;
    },
    computedColumns: {
      // cache: false,
      get() {
        let columns = this.options.columns;
        if (this.ColumnsInfo && this.ColumnsInfo.UseColumnContent) {
          columns = _.transform(this.ColumnsInfo.columnsInfo, (r, m) => {
            let optCol = this.options.columns.find((f) => f.dataField == m.ID);
            if (optCol) {
              r.push({ ...optCol, ...m, caption: optCol.caption });
            } else {
              r.push({ isShow: true, ...m });
            }
          });
        }
        columns = _.filter(columns, { isShow: true });

        let columnsWidthObj = {};
        if (false === this.isDevEnv && false !== this.options.saveColumnWidth) {
          let columnsWidth = this.getColumnsWidthFromStorage();
          columnsWidthObj = _.zipObject(
            _.map(columnsWidth, "df"),
            columnsWidth
          );
        }

        _.each(columns, (col) => {

          if (col.dataFormat && col.dataFormat.FormatType && this.isDevEnv !== true) {
            col.calculateDisplayValue = (rowData) => this.calculateDisplayValue(rowData, col)
            if (col.dataFormat.FormatType == "Discount") {
              // col.allowFiltering = false;
              col.calculateFilterExpression = (filterValue, selectedFilterOperation, target) => this.calculateFilterExpressionDiscount(filterValue, selectedFilterOperation, target, col)
              col.sortingMethod = (value1, value2) => {
                if (!value1 && value2) return 1;
                if (!value1 && !value2) return 0;
                if (value1 && !value2) return -1;
                // Determines whether two strings are equivalent in the current locale
                return value2 - value1;
              }
            }

            if (col.dataFormat.FormatType == "Percent") {
              // col.allowFiltering = false;
              col.calculateFilterExpression = (filterValue, selectedFilterOperation, target) => this.calculateFilterExpressionPercent(filterValue, selectedFilterOperation, target, col)
            }
          }

          col.name = col.dataField;
          let columnWidth = columnsWidthObj[col.dataField];
          if (columnWidth) {
            col.width = columnWidth.vw;
          }

          if (col.width === "") {
            if (this.isDevEnv !== true) {
              delete col.width;
            }
          }

          if (col && col.enumDisp && _.size(col.enumDisp.enumRanges) > 0) {
            if (this.isDevEnv !== true) {
              col.dataType = "string";
            }

            if(this.isDevEnv !== true){
              col.calculateFilterExpression=(value, selectedFilterOperations, target)=>this.calculateFilterExpressionCol(value, selectedFilterOperations, target, col)
            }

            return col;
          }

          if (col.dataType == "Date" || col.dataType == "date") {
            // let dataCol = { ...col };
            if (this.isDevEnv !== true) {
              col.dataType = "date";
              // col.format = "shortDate";
              col.format = (val) => Funcs.DateToString(val)
            }
            return col;
          } else if (
            col.dataType == "DateTime" ||
            col.dataType == "Timestamp"
          ) {
            if (this.isDevEnv !== true) {
              col.dataType = "datetime";
              // col.format = "shortDateShortTime";
              col.format = (val) => Funcs.DateTimeToString(val)
            }
          } else if (col.dataType == "Time" || col.dataType == "time") {
            if (this.isDevEnv !== true) {
              col.dataType = "datetime";
              // col.format = "longTime";
              col.format = (val) => Funcs.DateTimeToTime(val)
            }
          } else if (
            col.dataType == "Long" ||
            col.dataType == "Int" ||
            col.dataType == "Decimal"
          ) {
            if (this.isDevEnv !== true) {
              col.dataType = "number";
              col.format = "#0.############"
              col.editorOptions = { format: col.format, showClearButton: true }
            }
          } else if (col.dataType == "Boolean") {
            // 'string' | 'number' | 'date' | 'boolean' | 'object' | 'datetime'
            if (this.isDevEnv !== true) {
              col.dataType = "boolean";
            }
          } else if (col.dataType == "String") {
            // 'string' | 'number' | 'date' | 'boolean' | 'object' | 'datetime'
            if (this.isDevEnv !== true) {
              col.dataType = "string";
            }
          } else {
            // return _.omit(col, ["dataType"]);
            if (this.isDevEnv !== true) {
              delete col.dataType;
            }
            return col;
          }
        });

        this._rebindcomputedColumns(columns);

        return columns;
      },
    },
    IsSelectedRow() {
      return _.size(this.selectedRows) > 0;
    },
    SelectedRow() {
      return _.first(this.selectedRows);
    },
    optsCmdColConf() {
      return this.options.cmdColConfig || { columnConf: {}, commands: [] };
    },
    computedColCmds() {
      let commands = _.get(this.options, "cmdColConfig.commands", []);
      return commands;
    },
    propColumnHidingEnabled() {
      return this.platform == "pc" ? this.options.columnHidingEnabled : true;
    },
    IsLevelStructure(){
      return this.options.dataStructure == "plain_level";
    },
    computedLevelParentIdExpr() {
      return _.get(this.options, 'levelParentIdExpr', '_PLEVEL_')
    },
    computedDataStructure() {
      let isPlain_level = this.IsLevelStructure;
      return {
        dataStructure: isPlain_level ? "plain" : this.options.dataStructure,
        keyExpr: isPlain_level
          ? this.options.levelKeyExpr
          : this.options.keyExpr,
        parentIdExpr: isPlain_level
          ? this.computedLevelParentIdExpr
          : this.options.parentIdExpr,
        rootValue: isPlain_level
          ? ""
          : this.options.rootValue,
      };
    },
  },
  watch: {
    dataSource(val){
      debugger;
      if(this.IsLevelStructure){
        this.getHasFilter(true);
        if (false == this.hasFilter) {
          this.convertLevel2ParentId(val, this.options.levelKeyExpr, this.computedLevelParentIdExpr);
        } else {
          _.each(val, item => { item['_hasChildCode_'] = false });
        }
      }else{
        if (!this.isDevEnv) {
          this.options.parentIdExpr = _.trimStart(this.options.parentIdExpr, "_")
          this.getHasFilter(true);
          if (this.hasFilter) {
            _.each(val, item => {
              item['_hasChildCode_'] = false
              item[`_${this.computedDataStructure.parentIdExpr}`] = this.options.rootValue;
            });
            this.options.parentIdExpr = `_${this.options.parentIdExpr}`;
          }
        }
      }
      // if(!this.options.lazyItems){
      //   this.CollapsAll();
      // }
    },
    ShowAutoFilterRow(val) {
      if (this.widgetInstance) {
        this.widgetInstance.clearFilter();
      }
    },
  },
  destroyed(){
    if(this.observerScrollableScrollStyle && this.observerScrollableScrollStyle.disconnect){
      this.observerScrollableScrollStyle.disconnect();
    }
  },
  data() {
    let that = this;

    this.ignoreParams=[];
    let dataSource = [];
    // let getDataSource = dataSource;
    // if (this.options.lazyItems && true !== this.isDevEnv) {
    //   this.loadByLazyCode("");
    // }
    this.observerScrollableScrollStyle = new MutationObserver(this.cbScrollableScrollStyleMutationObserver);

    return {
      Term:TermsTreeList,
      confOffsetHeight: 0,
      selectedRows: [],
      // getDataSource: getDataSource,
      ColumnsInfo: {},
      dataSource,
      LazyCode: that.options.lazyCode || "",
      showColConf: false,
      expandedRowKeys:[],
      selectedRowKeys:[],
      hasFilter:false,
    };
  },
};
</script>